Skip to content

Serve the OpenAPI document at /openapi.json, as NodeNorm Redis does - #49

Open
gaurav wants to merge 1 commit into
biothings:mainfrom
TranslatorSRI:serve-openapi-at-root
Open

gaurav wants to merge 1 commit into
biothings:mainfrom
TranslatorSRI:serve-openapi-at-root

Conversation

@gaurav

@gaurav gaurav commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

main makes /openapi.json redirect to /webapp/openapi.json. This PR serves the document at /openapi.json directly instead, which is where NodeNorm Redis (FastAPI's default) and most Translator services serve theirs, and points the Swagger UI at / there. Clients that fetch /openapi.json get the document without following a redirect, and the root address becomes the canonical one.

Calls worth overruling

  • /webapp/openapi.json keeps working. It costs nothing, because the existing /webapp/(.*) asset handler already serves the file. Babel Validation's tests/targets.ini sets NodeNormOpenAPIPath = webapp/openapi.json for the ES deployments, and the Translator diagram's components/nodenorm-es.yaml does the same, so removing that address would break both. Once this is deployed, both can drop the override and use the default.
  • The file stays at src/nodenorm/webapp/openapi.json. Only the route changes; /status and the tests read the file there, so moving it would only add churn.

For the reviewer

The same change could be applied to NameRes ES (biothings/NameResolutionAPI), which has the same /webapp layout and serves its document only at /webapp/openapi.json, unlike NameRes Redis. The node annotator is in the same position. This PR changes only NodeNorm ES. If you'd like NameRes ES to match, it would be a separate PR in that repository (which could also escape the dot in its /favicon.ico route, as this repository's main does), and the Translator diagram's component-metadata.md, which currently calls webapp/openapi.json the intended convention for these services, would need updating too.

Verification

On 8e5548d, all 290-odd tests pass except the four integration tests that need the su10 host, which weren't run. They check that both addresses return the document with a JSON content type, that the served document is valid OpenAPI, that /openapiXjson is a 404, and that the Swagger UI at / loads /openapi.json. The Swagger UI wasn't opened in a browser.

Nothing is blocking.

🤖 Generated with Claude Code

/openapi.json redirected to /webapp/openapi.json. It now serves the
document itself, which is where NodeNorm Redis (FastAPI's default) and
most Translator services serve theirs, and the Swagger UI at / loads it
from there.

/webapp/openapi.json keeps working through the existing /webapp asset
handler, because Babel Validation's targets.ini and the Translator
diagram's nodenorm-es component are configured with that address.
Removing it would break them and gain nothing; they can switch to the
default once this is deployed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
gaurav added a commit to TranslatorSRI/babel-validation that referenced this pull request Nov 6, 2026
…release-name parser (#76)

This PR adds regression tests for six NodeNorm ES bugs. Four were fixed
before this PR, so their tests guard against a return. The other two
were found on 2026-09-29 while tracing why ORION's build against
NodeNorm ES normalized differently from its build against Redis
(biothings/NodeNormalizationAPI#40, #41); both are closed upstream but
not yet deployed to `ci`. It also adds `/status` checks that catch a
deployment reporting no backend, a malformed Babel release name, or a
broken release-notes link.

The checks these tests share now live in the `babel_validation` package
rather than under `tests/`, so Babel release names can be parsed and
compared by anything that installs it.

Best reviewed alongside #153 (NodeNorm ES response shapes against its
OpenAPI document; the two collide only in `CLAUDE.md`'s Testing
Patterns) and #157 (NameRes `/synonyms`, and `ci-nameres-es` on the
dashboard; collides only on an import line). #156, stacked on this one,
adds a tool for diffing two NodeNorm targets, to be reviewed with #148.

## Calls worth overruling

- **Open bugs are strict xfails keyed on the target's backend.**
`test_issue_40` and `test_issue_41` pass on Redis and xfail where
`targets.ini` says `NodeNormBackend = elasticsearch`; when the fixes
reach `ci`, the unexpected passes say the markers can come out. The
other four bugs are fixed, so their tests carry no xfail.
`test_nodenorm_229` uses the same setting to skip ES, which has no
`/query`, rather than probing for it.
- **Every target states its NodeNorm backend; `redis` is only the
default for a new one.** A new deployment of either kind is unlikely, a
Redis one slightly less so. Each target also states its OpenAPI path,
and `tests/unit/test_targets_ini.py` checks each backend's OpenAPI path.
That path setting can go once biothings/NodeNormalizationAPI#49 (open),
which serves the document at `/openapi.json`, reaches every ES target;
`targets.ini` says how.
- **Release-specific tests skip older deployments and fail unreadable
ones.** `require_babel_release()` skips a target serving an earlier
Babel (today `test` and `prod`, on 2025sep1). One whose `/status` cannot
be fetched, or reports no well-formed `babel_version`, fails: a skip
would make a run green that tested nothing. A successful `/status` is
cached per target; a failure is not.
- **A missing `/status` field fails rather than skips**, since every
current NodeNorm release reports `backend`, `babel_version` and
`babel_version_url`. `test_status_backend` still skips a target with no
`backend`, naming `test_status_backend_is_known` as the one that reports
it.
- **`babel_version_url` is never fetched as given.** The test builds the
URLs it would accept from the validated `babel_version` (`main` or
`master`, `releases/<v>.md` or the newer `releases/<v>/README.md`,
NCATSTranslator/Babel#1021) and fetches its own copy. Dropping the old
shape is #147.
- **The expected infores depends on the backend:** `infores:nodenorm`
from ES, `infores:sri-node-normalizer` from Redis
(biolink/information-resource-registry#140).
- **The shared code is split by what it needs.**
`src/babel_validation/core/babel_release.py` recognises and orders
release names with the standard library only.
`src/babel_validation/services/service_checks.py` holds the checks that
fail or skip a test; they check a response's shape before reading it and
`repr()`-escape whatever a service returns.

## What's here

Regression tests in `tests/nodenorm/by_issue/biothings/`, run against
every target: biothings/NodeNormalizationAPI#10 (an HTTP 500 under
`drug_chemical_conflate`), #11 (duplicate `equivalent_identifiers`,
checked for duplicates only, since its counts were one release's
cliques), #14 (a 500 from one pair of CURIEs, queried together and
apart), biothings/pending.api#338 (`NCBITaxon:2` null beside
`MESH:C029371`), #40 (`Food.txt` and `CellLine.txt` never loaded) and
#41 (a duplicate clique leader's two types merged into one list).

`tests/nodenorm/test_nodenorm_api.py` adds the `/status` checks;
NodeNorm ES has reported `1.9` and `VERSION.txt` as its `babel_version`,
both unit-tested.
[`tests/nodenorm/by_issue/biothings/CLAUDE.md`](https://github.com/TranslatorSRI/babel-validation/blob/c995d1b/tests/nodenorm/by_issue/biothings/CLAUDE.md)
records how to investigate ES against Redis, and to recommend closing an
issue whose test passes while it is still open. `CLAUDE.md` documents
the new modules, what belongs in `tests/nodenorm/by_issue/`, and `data/`
as scratch space.

## Status at merge

On `fee6ebb`, the changed tests against prod, test, ci, ci-nameres-es,
dev and exp: 185 passed, 36 xfailed (#40 and #41 on the two `ci`
targets), 42 skipped (release-gated tests on prod and test, #229 on ES),
7 failed. All 240-odd unit tests pass. None of the failures is this
PR's:

- **NodeNorm `test_openapi_json`, dev and exp (Redis):** the `max_edges`
schema bug, NCATSTranslator/NodeNormalization#409.
- **NodeNorm `test_openapi_json`, prod (ES 1.0.0):** an invalid document
still declaring `infores:sri-node-normalizer`; ES 1.2.0 on `ci` and
`test` passes.
- **NameRes `test_openapi_json`, ci, test and dev (v1.7.0):** no
`x-translator`; fixed by NCATSTranslator/NameResolution#300, in the
v1.7.1 pre-release.
- **NameRes `test_reverse_lookup`, ci-nameres-es:** the ES NameRes has
no `/reverse_lookup`; #157 moves the test to `/synonyms`.

Nothing blocks merging. Deferred: #147. The Babel-side causes of #40 and
#41 are NCATSTranslator/Babel#276 and NCATSTranslator/Babel#1123.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
@gaurav
gaurav force-pushed the serve-openapi-at-root branch from e33e84d to 8e5548d Compare November 9, 2026 19:42
@gaurav
gaurav marked this pull request as ready for review November 9, 2026 20:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant